#if defined(ORATR_USE_HTTP)
#include <stdio.h>
#include "http_download.h"
#include <iostream>
using std::cout;

#define RECV_BUFFER_SIZE	256

CHttpDownload::CHttpDownload( void ): CWinTcpSocket()
{

}

int CHttpDownload::DownloadFile( const char *pszRemoteFile, const char *pszLocalFile )
{
	char *pMemBuf;

	if( !MakeRequest( pszRemoteFile ) ) {
		return HTTPERR_REQUEST;
	}

	pMemBuf = new char[ RECV_BUFFER_SIZE ];

	if( pMemBuf == 0 ) {
		return HTTPERR_MEMORY;
	}

	if( GetResponse( pMemBuf ) != 0 ) {
		return HTTPERR_RESPONSE;
	}

	if( !IsResponseOK( pMemBuf ) ) {
		return HTTPERR_NOTOK;
	}

	delete[] pMemBuf;

	if( SkipHeader() != 0 ) {
		return HTTPERR_HEADERSKIP;
	}

	return WriteToFile( pszLocalFile );
}

int CHttpDownload::DownloadArray( const char *pszRemoteFile, string& data )
{
	char *pMemBuf;

	if( !MakeRequest( pszRemoteFile ) ) {
		return HTTPERR_REQUEST;
	}

	pMemBuf = new char[ RECV_BUFFER_SIZE ];

	if( pMemBuf == 0 ) {
		return HTTPERR_MEMORY;
	}

	if( GetResponse( pMemBuf ) != 0 ) {
		return HTTPERR_RESPONSE;
	}

	if( !IsResponseOK( pMemBuf ) ) {
		return HTTPERR_NOTOK;
	}

	delete[] pMemBuf;

	if( SkipHeader() != 0 ) {
		return HTTPERR_HEADERSKIP;
	}
	
	return WriteToString(data);
}


bool CHttpDownload::MakeRequest( const char *pszRequest )
{
	char *pReqStr = new char[ 32 + strlen( pszRequest ) ];
	sprintf( pReqStr, GET_REQUEST_FORMAT, pszRequest );
	int nErr = SendText( pReqStr );
	delete[] pReqStr;

	if( nErr == 0 || nErr == SOCKET_ERROR ) {
		return false;
	} else {
		return true;
	}
}

int CHttpDownload::GetResponse( char *pszBuf )
{
	int nErr = RecvLine( pszBuf, RECV_BUFFER_SIZE );

	if( nErr == 0 || nErr == SOCKET_ERROR ) {
		return HTTPERR_DISCONNECTED;
	} else {
		return 0;
	}
}

bool CHttpDownload::IsResponseOK( const char *pszResponse )
{
	if( strstr( pszResponse, HTTP_OK_STRING ) == 0 ) {
		return false;
	} else {
		return true;
	}
}

int CHttpDownload::SkipHeader( void )
{
	int nLen;
	bool bFound = false;
	char cur = 0, prev_1 = 0, prev_2 = 0, prev_3 = 0;

	while( !bFound ) {
		nLen = Recv( &cur, 1 );

		if( nLen == 0 || nLen == SOCKET_ERROR ) {
			return HTTPERR_DISCONNECTED;
		}

		if( (cur == '\n') && (prev_1 == '\r') && (prev_2 == '\n') && (prev_3 == '\r') ) {
			bFound = true;
		} else {
			prev_3 = prev_2;
			prev_2 = prev_1;
			prev_1 = cur;
		}
	}

	return 0;
}

int CHttpDownload::WriteToFile( const char *pszFile )
{
	char *pBuf = new char[ RECV_BUFFER_SIZE ];
	FILE *pFile = fopen( pszFile, "w+b" );
	int nErr;

	if( pFile == 0 ) {
		cout << "Could not open destination file\n";
		return HTTPERR_FILEIO;
	}

	while(1) {
		nErr = Recv( pBuf, RECV_BUFFER_SIZE );

		if( nErr == 0 ) {
			break;
		} else if( nErr == SOCKET_ERROR ) {
			fclose( pFile );
			delete[] pBuf;

			return HTTPERR_DISCONNECTED;
		} else {
			fwrite( pBuf, sizeof( char ), nErr, pFile );
		}
	}

	fclose( pFile );
	delete[] pBuf;

	return 0;
}

int CHttpDownload::WriteToString( string &pszStr )
{
	char *pBuf = new char[ RECV_BUFFER_SIZE ];
	int nErr;
	
	while(1) {
		nErr = Recv( pBuf, RECV_BUFFER_SIZE );

		if( nErr == 0 ) {
			break;
		} else if( nErr == SOCKET_ERROR ) {
			delete[] pBuf;

			return HTTPERR_DISCONNECTED;
		} else {
			pszStr += pBuf;
		}
	}

	delete[] pBuf;
	return 0;
}
#endif
